Fix declaration guard injection in SMT translator#59
Conversation
Guards on declarations (e.g., `value t: Thing, active? t => Nat0`) were causing spurious "not preserved" warnings due to two bugs: 1. Guards were injected into postconditions, making user-written frame conditions vacuous for unguarded elements. Postconditions define the transition relation and should be asserted as-is. Fixed by adding an `inject_guards` flag to config and disabling it for postcondition translation sites. 2. Primed applications (e.g., `value' t` in post-state invariants) were skipped by `collect_body_guards`, so post-state invariant copies lost their guards while pre-state copies kept them. Fixed by handling `EApp(EPrimed name, args)` and bare `EPrimed name` cases, collecting guards in primed form via `prime_expr ~bound`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughA new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis PR fixes two critical bugs in SMT translation of declaration guards. The fix prevents spurious invariant preservation warnings that occur when guards on declarations (e.g., Key changes:
Bug fixes:
Testing:
Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[SMT Config] -->|inject_guards flag| B{Translation Site}
B -->|Invariant/Frame| C[inject_guards = true]
B -->|Postcondition| D[inject_guards = false]
C --> E[collect_body_guards]
D --> F[translate_proposition]
E -->|EApp EPrimed name, args| G[Handle Primed Apps]
E -->|EPrimed name| H[Handle Bare Primed]
G --> I[prime_expr with ~bound]
H --> I
I --> J[Primed Guard: active?' t]
F --> K[No Guard Injection]
C --> L[Guard Antecedent Added]
K --> M[Postcondition Defines Transition]
L --> N[Invariant Checking in Next State]
Last reviewed commit: 8cdc2f9 |
Summary
value t: Thing, active? t => Nat0) were injected into postconditions, making user-written frame conditions vacuous for unguarded elements and producing spurious "not preserved" warnings. Fixed by adding aninject_guardsconfig flag and disabling it for postcondition translation sites.value' tin post-state invariants) were skipped bycollect_body_guards, so post-state invariants lost their guard antecedents while pre-state copies kept them. Fixed by handlingEApp(EPrimed name, args)and bareEPrimed namecases, collecting guards in primed form viaprime_expr ~bound.samples/smt-examples/guarded-frame.pant)Test plan
dune buildcompiles without errorsdune test— all 106 SMT tests pass (3 new)pant --check /tmp/guard-test.pant— all OK, no spurious WARNpant --check samples/smt-examples/guarded-frame.pant— all OKpant --check fgp-buy.pant— regression passes (no declaration guards in this spec)performedpin pre-state invariant,performedp_primein post-state invariant🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests